package com.compayname.projectname.util;

//import cn.eshore.common.consts.Constants;
//import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
//import org.apache.http.entity.mime.HttpMultipartMode;
//import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.junit.platform.commons.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpClientUtils {

	private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);

	private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(20000).setConnectionRequestTimeout(20000)
			.build();

	/**
	 * 发送 get请求
	 * 
	 * @param httpUrl
	 * @param maps
	 */
	public static String sendHttpGet(String httpUrl, Map<String, String> maps, Map<String, String> heads) throws Exception {
		CloseableHttpClient httpClient = httpClient();
		HttpResponse response = null;

		String params = "";
		if (maps != null) {
			for (String key : maps.keySet()) {
				params = params + key + "=" + URLEncoder.encode(maps.get(key), "UTF-8") + "&";
			}
			params = params.substring(0, params.length() - 1);
		}
		if (StringUtils.isNotBlank(params)) {
			httpUrl += "?";
			httpUrl += params;
		}
		logger.debug("GET URL:{}", httpUrl);

		HttpGet request = new HttpGet(httpUrl);
		request.setConfig(requestConfig);

		if (heads != null && heads.size() > 0) {
			for (Map.Entry<String, String> entry : heads.entrySet()) {
				logger.debug("GET HEAD:{}|{}", entry.getKey(), entry.getValue());
				request.addHeader(entry.getKey(), entry.getValue());
			}
		}
		response = httpClient.execute(request);
		String result = "";
		HttpEntity entity = response.getEntity();
		if (entity != null) {
			result = EntityUtils.toString(response.getEntity(), "utf-8");
		}
		httpClient.close();
		return result;
	}

	public static String sendPutRequest(String url, Map<String, String> param, Map<String, String> heads) throws Exception {
		CloseableHttpClient httpclient = httpClient();
		HttpPut httpPut = new HttpPut(url);

		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		for (String key : param.keySet()) {
			nameValuePairs.add(new BasicNameValuePair(key, param.get(key)));
		}
		httpPut.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));

		if (heads != null && heads.size() > 0) {
			for (Map.Entry<String, String> entry : heads.entrySet()) {
				logger.debug("POST HEAD:{}|{}", entry.getKey(), entry.getValue());
				httpPut.addHeader(entry.getKey(), entry.getValue());
			}
		}
		HttpResponse response = httpclient.execute(httpPut);
		String result = "";
		HttpEntity entity = response.getEntity();
		if (entity != null)
			result = EntityUtils.toString(entity);
		httpclient.close();
		return result;
	}

	/**
	 * 发送 post请求
	 * 
	 * @param httpUrl
	 */
	public static String sendHttpPost(String httpUrl) throws Exception {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
		return sendHttpPost(httpPost);
	}
	
	/**
	 * 发送 put请求,一般使用application/json
	 * 
	 * @param contentType-指定Content-Type
	 * @param httpUrl-地址
	 * @param params-参数(格式:key1=value1&key2=value2)
	 * @param heads-指定头信息
	 */
	public static String sendHttpPut(String contentType, String httpUrl, String params, Map<String, String> heads) throws Exception {
		HttpPut httpPut = new HttpPut(httpUrl);// 创建httpPost
		// 设置参数
		StringEntity stringEntity = new StringEntity(params, "UTF-8");
		stringEntity.setContentType(contentType);
		if (heads != null && heads.size() > 0) {
			for (Map.Entry<String, String> entry : heads.entrySet()) {
				logger.debug("POST HEAD:{}|{}", entry.getKey(), entry.getValue());
				httpPut.addHeader(entry.getKey(), entry.getValue());
			}
		}
		httpPut.setEntity(stringEntity);
		return sendHttpPut(httpPut);
	}

	/**
	 * 发送 post请求,一般使用application/json
	 * 
	 * @param contentType-指定Content-Type
	 * @param httpUrl-地址
	 * @param params-参数(格式:key1=value1&key2=value2)
	 * @param heads-指定头信息
	 */
	public static String sendHttpPost(String contentType, String httpUrl, String params, Map<String, String> heads) throws Exception {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
		// 设置参数
		StringEntity stringEntity = new StringEntity(params, "UTF-8");
		stringEntity.setContentType(contentType);
		if (heads != null && heads.size() > 0) {
			for (Map.Entry<String, String> entry : heads.entrySet()) {
				logger.debug("POST HEAD:{}|{}", entry.getKey(), entry.getValue());
				httpPost.addHeader(entry.getKey(), entry.getValue());
			}
		}
		httpPost.setEntity(stringEntity);
		return sendHttpPost(httpPost);
	}

	/**
	 * 发送 post请求,使用普通的:x-www-form-urlencoded形式
	 * 
	 * @param httpUrl-地址
	 * @param maps-参数(格式:key1=value1&key2=value2)
	 * 
	 */
	public static String sendHttpPostOriginal(String httpUrl, Map<String, String> maps, Map<String, String> heads) throws Exception {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost
		if (heads != null && heads.size() > 0) {
			for (Map.Entry<String, String> entry : heads.entrySet()) {
				logger.debug("POST HEAD:{}|{}", entry.getKey(), entry.getValue());
				httpPost.addHeader(entry.getKey(), entry.getValue());
			}
		}
		String params = "";
		for (String key : maps.keySet()) {
			params = params + key + "=" + URLEncoder.encode(maps.get(key), "UTF-8") + "&";
		}
		params = params.substring(0, params.length() - 1);

		// 设置参数
		StringEntity stringEntity = new StringEntity(params, "UTF-8");
		stringEntity.setContentType("application/x-www-form-urlencoded");
		httpPost.setEntity(stringEntity);
		return sendHttpPost(httpPost);
	}

	/**
	 * 发送 post请求,使用键值对NameValuePair组装参数
	 * 
	 * @param httpUrl-地址
	 * @param maps-参数
	 * 
	 */
	public static String sendHttpPost(String httpUrl, Map<String, String> maps, Map<String, String> heads) throws Exception {
		HttpPost httpPost = new HttpPost(httpUrl);

		if (heads != null && heads.size() > 0) {
			for (Map.Entry<String, String> entry : heads.entrySet()) {
				logger.debug("POST HEAD:{}|{}", entry.getKey(), entry.getValue());
				httpPost.addHeader(entry.getKey(), entry.getValue());
			}
		}
		// 创建参数队列
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		for (String key : maps.keySet()) {
			nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
		}
		httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
		httpPost.setHeader("Content-Type", "multipart/form-data");
		logger.debug("POST length:{}", httpPost.getEntity().getContentLength());
		logger.debug("POST type:{}", httpPost.getEntity().getContentType());
		logger.debug("POST chunk:{}", httpPost.getEntity().isChunked());
		logger.debug("POST content:{}", httpPost.getEntity().getContent());
		return sendHttpPost(httpPost);
	}

	/**
	 * 发送Post请求,核心请求
	 * 
	 * @param httpPost
	 * @return
	 */
	private static String sendHttpPost(HttpPost httpPost) throws Exception {
		CloseableHttpClient httpClient = httpClient();
		HttpResponse response = null;
		HttpEntity entity = null;
		String result = null;
		httpPost.setConfig(requestConfig);
		response = httpClient.execute(httpPost);
		entity = response.getEntity();
		if (entity != null) {
			result = EntityUtils.toString(entity, "UTF-8");
		}
		httpClient.close();
		return result;
	}
	
	/**
	 * 发送Put请求,核心请求
	 * 
	 * @param httpPut
	 * @return
	 */
	private static String sendHttpPut(HttpPut httpPut) throws Exception {
		CloseableHttpClient httpClient = httpClient();
		HttpResponse response = null;
		HttpEntity entity = null;
		String result = null;
		httpPut.setConfig(requestConfig);
		response = httpClient.execute(httpPut);
		entity = response.getEntity();
		if (entity != null) {
			result = EntityUtils.toString(entity, "UTF-8");
		}
		httpClient.close();
		return result;
	}

	/**
	 * ===========================忽略HTTPS证书=====================================
	 **/
	public static CloseableHttpClient httpClient() {
		SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(sslContext(), hostnameVerifier());
		return HttpClients.custom().setDefaultRequestConfig(requestConfig).setSSLSocketFactory(sslFactory).build();
	}

	public static SSLContext sslContext() {
		try {
			return SSLContexts.custom().loadTrustMaterial(null, trustStrategy()).build();
		} catch (Exception e) {
			return SSLContexts.createDefault();
		}
	}

	public static TrustStrategy trustStrategy() {
		return (X509Certificate[] chain, String authType) -> true;
	}

	public static HostnameVerifier hostnameVerifier() {
		return (hostname, sslSession) -> true;
	}

	public static String sendPostRequest(String url, List<NameValuePair> nameValuePairs, Header authHeader) throws IOException {
		CloseableHttpClient httpclient = httpClient();
		HttpPost httpPost = new HttpPost(url);
		httpPost.setHeader(authHeader);
		httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
		HttpResponse response = httpclient.execute(httpPost);
		String result = "";
		HttpEntity entity = response.getEntity();
		if (entity != null)
			result = EntityUtils.toString(entity);
		httpclient.close();
		return result;
	}

//	public static String sendHttpPostFile(String url, MultipartFile file, Map<String, String> params, Map<String, String> heads) throws Exception {
//		InputStream stream=null;
//		try {
//			CloseableHttpClient httpclient = httpClient();
//			CloseableHttpResponse response = null;
//			String result = "";
//			HttpPost httpPost = new HttpPost(url);
//			if (heads != null && heads.size() > 0) {
//				for (Map.Entry<String, String> entry : heads.entrySet()) {
//					logger.debug("POST HEAD:{}|{}", entry.getKey(), entry.getValue());
//					httpPost.addHeader(entry.getKey(), entry.getValue());
//				}
//			}
//			MultipartEntityBuilder mEntityBuilder = MultipartEntityBuilder.create();
//			mEntityBuilder.setCharset(java.nio.charset.Charset.forName("UTF-8"));
//			mEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
//			mEntityBuilder.setBoundary(Constants.UPLOAD_IMAGE_BOUNDARY);
//			stream=file.getInputStream();
//			mEntityBuilder.addBinaryBody("file", stream, ContentType.MULTIPART_FORM_DATA, file.getOriginalFilename());
//			if (params != null && params.size() > 0) {
//				for (Map.Entry<String, String> entry : params.entrySet()) {
//					logger.debug("POST PARAMS:{}|{}", entry.getKey(), entry.getValue());
//					mEntityBuilder.addTextBody(entry.getKey(), entry.getValue());
//				}
//			}
//			httpPost.setEntity(mEntityBuilder.build());
//			response = httpclient.execute(httpPost);
//			HttpEntity entity = response.getEntity();
//			if (entity != null)
//				result = EntityUtils.toString(entity);
//			httpclient.close();
//			return result;
//		}catch(Exception e) {
//			throw e;
//		}finally {
//			if(stream!=null) {
//				stream.close();
//			}
//		}
//	}

	public static void main(String[] args) {
		String url = "http://127.0.0.1/client/userAdd";
		Map<String, String> headMap = new HashMap<String, String>();
		headMap.put("resource-id", "AP000001");
		headMap.put("app-id", "Ib0nb8PKGYYZ");
		headMap.put("ver", "1.0");

		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("token", "AP000001:Ib0nb8PKGYYZ:1587667351347:4wRs9zAMCWa/IeedxJe+ig==");
		paramMap.put("userName", "张三");
		paramMap.put("idNum", "4401041234567890");

		File pdfFile = new File("C:\\Users\\Windows10\\Desktop\\20200327T121848_207_208_0_42949672963.jpg");
		try {
//			HttpClientUtils.sendHttpPostFile(url, pdfFile, paramMap, headMap);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}
